﻿using System;
using System.Collections.Generic;
using System.Text;

using DigitalQuran.Collection;
using DigitalQuran.Extensions;
using DigitalQuran.Numerology;
using DigitalQuran.IO;

namespace DigitalQuran.Research {
    /*
    public static class Research {
        private static void FindBismAllahIsAlFatihaSystem(ResearchAgent agent) {
            // Creat Client Settings Backup
            var backup = new ClientSettingsBackup(agent.Client);
            
            NumberType[] numberTypes = (NumberType[])Enum.GetValues(typeof(NumberType));

            foreach (NumberType nType in numberTypes) {
                DateTime startTime = DateTime.Now;

                if ((nType == NumberType.Prime) ||
                    (nType == NumberType.AdditivePrime) ||
                    (nType == NumberType.PurePrime)) {

                    long minDifference = long.MaxValue;

                    var allNumerologySystems = new List<NumerologySystem>();
                    var zeroDifferenceNumerologySystems = new List<NumerologySystem>();
                    var bestDifferenceNumerologySystems = new List<NumerologySystem>();

                    int PERMUTATIONS = 524288;
                    for (int i = 0; i < PERMUTATIONS; i++) {
                        NumerologySystem numerology_system = new NumerologySystem();
                        numerology_system.Name = key;
                        numerology_system.AddToLetterLNumber = ((i & 262144) != 0);
                        numerology_system.AddToLetterWNumber = ((i & 131072) != 0);
                        numerology_system.AddToLetterVNumber = ((i & 65536) != 0);
                        numerology_system.AddToLetterCNumber = ((i & 32768) != 0);
                        numerology_system.AddToLetterLDistance = ((i & 16384) != 0);
                        numerology_system.AddToLetterWDistance = ((i & 8192) != 0);
                        numerology_system.AddToLetterVDistance = ((i & 4096) != 0);
                        numerology_system.AddToLetterCDistance = ((i & 2048) != 0);
                        numerology_system.AddToWordWNumber = ((i & 1024) != 0);
                        numerology_system.AddToWordVNumber = ((i & 512) != 0);
                        numerology_system.AddToWordCNumber = ((i & 256) != 0);
                        numerology_system.AddToWordWDistance = ((i & 128) != 0);
                        numerology_system.AddToWordVDistance = ((i & 64) != 0);
                        numerology_system.AddToWordCDistance = ((i & 32) != 0);
                        numerology_system.AddToVerseVNumber = ((i & 16) != 0);
                        numerology_system.AddToVerseCNumber = ((i & 8) != 0);
                        numerology_system.AddToVerseVDistance = ((i & 4) != 0);
                        numerology_system.AddToVerseCDistance = ((i & 2) != 0);
                        numerology_system.AddToChapterCNumber = ((i & 1) != 0);

                        // this will update the numerology system including its count of letters and their values (Values.Count)
                        long difference = CalculateBismAllahAndAlFatihaDifference(ref numerology_system, nType);

                        allNumerologySystems.Add(numerology_system);

                        if (difference == 0L) {
                            zeroDifferenceNumerologySystems.Add(numerology_system);
                            Console.WriteLine(numerology_system.ToSummary());
                            // break;   // don't break in case there are more systems with zero difference
                        } else {
                            if (Math.Abs(difference) > minDifference) {
                                continue;
                            } else if (Math.Abs(difference) == minDifference) {
                                bestDifferenceNumerologySystems.Add(numerology_system);
                            } else if (Math.Abs(difference) < minDifference) {
                                minDifference = Math.Abs(difference);
                                bestDifferenceNumerologySystems.Clear();

                                bestDifferenceNumerologySystems.Add(numerology_system);
                            }
                        }
                    } // PERMUTATIONS loop
                    
                    string filename = "FindBismAllahIsAlFatiha" + nType.ToString() + "IndexSystem";
                    string path = LocalResearchDirectory + "/" + filename;

                    StringBuilder str = new StringBuilder();
                    str.AppendLine("TextMode" +
                                    "\t" + "LetterOrder" +
                                    "\t" + "LetterValues" +
                                    "\t" + "TextScope" +
                                    "\t" + "AddToLetterLNumber" +
                                    "\t" + "AddToLetterWNumber" +
                                    "\t" + "AddToLetterVNumber" +
                                    "\t" + "AddToLetterLDistance" +
                                    "\t" + "AddToLetterWDistance" +
                                    "\t" + "AddToLetterVDistance" +
                                    "\t" + "AddToLetterLWVNumber" +
                                    "\t" + "AddToLetterVWLNumber" +
                                    "\t" + "AddToLetterLWVDistance" +
                                    "\t" + "AddToLetterVWLDistance" +
                                    "\t" + "AddToWordWNumber" +
                                    "\t" + "AddToWordVNumber" +
                                    "\t" + "AddToWordWDistance" +
                                    "\t" + "AddToWordVDistance" +
                                    "\t" + "AddToWordWVNumber" +
                                    "\t" + "AddToWordVWNumber" +
                                    "\t" + "AddToWordWVDistance" +
                                    "\t" + "AddToWordVWDistance" +
                                    "\t" + "AddToVerseVNumber" +
                                    "\t" + "AddToVerseVDistance" +
                                    "\t" + "BismAllah" +
                                    "\t" + "AlFatiha" + nType.ToString() + "Index" +
                                    "\t" + "Difference"
                                );

                    if (allNumerologySystems != null) {
                        if (allNumerologySystems.Count > 0) {
                            foreach (NumerologySystem numerology_system in allNumerologySystems) {
                                str.AppendLine(numerology_system.ToSummary());
                            }
                        }
                    }

                    str.AppendLine();
                    str.AppendLine(allNumerologySystems.Count.ToString() + " systems were tested.");
                    str.AppendLine(bestDifferenceNumerologySystems.Count.ToString() + " best-difference systems were found.");
                    str.AppendLine(zeroDifferenceNumerologySystems.Count.ToString() + " zero-difference systems were found.");
                    str.AppendLine();
                    if (bestDifferenceNumerologySystems.Count > 0) {
                        str.AppendLine("------------- Best-Difference Systems -------------");
                        foreach (NumerologySystem numerology_system in bestDifferenceNumerologySystems) {
                            str.AppendLine(numerology_system.ToSummary());
                            str.AppendLine();
                        }
                        str.AppendLine("-----------------------------------------------");
                        str.AppendLine();
                    }
                    if (zeroDifferenceNumerologySystems.Count > 0) {
                        str.AppendLine();
                        str.AppendLine("------------- Zero-Difference Systems -------------");
                        foreach (NumerologySystem numerology_system in zeroDifferenceNumerologySystems) {
                            str.AppendLine(numerology_system.ToString());
                            str.AppendLine();
                        }
                        str.AppendLine("---------------------------------------------------");
                        str.AppendLine();
                    }

                    TimeSpan elapsed_time = DateTime.Now - startTime;
                    str.AppendLine("Elapsed Time: " + elapsed_time.ToString());

                    PublicStorage.SaveText(path, str.ToString());
                    client.DisplayFile("Research", path);

                    // free memeory
                    for (int i = 0; i < allNumerologySystems.Count; i++) {
                        allNumerologySystems[i] = null;
                    }
                    for (int i = 0; i < zeroDifferenceNumerologySystems.Count; i++) {
                        zeroDifferenceNumerologySystems[i] = null;
                    }
                    for (int i = 0; i < bestDifferenceNumerologySystems.Count; i++) {
                        bestDifferenceNumerologySystems[i] = null;
                    }
                    allNumerologySystems = null;
                    zeroDifferenceNumerologySystems = null;
                    bestDifferenceNumerologySystems = null;
                    GC.Collect();
                }
            }
        }

        private static string s_previous_numerology_system_name;
        private static TextScope s_previous_numerology_system_text_scope;

        private static long CalculateBismAllahAndAlFatihaDifference(ResearchAgent agent, NumerologySystem numerologySystem, NumberType nType) {
            long valueDifference = long.MaxValue;

            // only update if numerology system name OR text_scope has changed
            if (
                ||
                (numerologySystem.Name != s_previous_numerology_system_name)
                ||
                (numerologySystem.TextScope != s_previous_numerology_system_text_scope)
                ) {
                s_previous_numerology_system_name = numerologySystem.Name;
                s_previous_numerology_system_text_scope = numerologySystem.TextScope;

                switch (numerologySystem.TextScope) {
                    case TextScope.Book: {
                            Client.UpdateNumerologySystems(numerologySystem.TextMode, book.GetText(numerologySystem.TextMode), true);
                        }
                        break;
                    case TextScope.Selection: {
                            Client.UpdateNumerologySystems(numerologySystem.TextMode, book.Chapters[0].GetText(numerologySystem.TextMode), false);
                        }
                        break;
                    case TextScope.HighlightedText: {
                            Client.UpdateNumerologySystems(numerologySystem.TextMode, book.Verses[0].GetText(numerologySystem.TextMode), false);
                        }
                        break;
                    default: {
                        }
                        break;
                }
            }
            
            // update numerology_system with values
            //numerologySystem.Values = new Dictionary<char, long>(agent.Client.Numerology[numerologySystem.ToString()]);

            var chapter = Book.Instance.Chapters[0];
            Client.Instance.Numerology.CalculateValue(chapter, numerologySystem);

            var alfatihaValue = chapter.Value;
            var bismAllahValue = chapter.Verses[0].Value;                
            
            long alfatihaValueIndex = -1;
            switch (nType) {
                case NumberType.Prime:
                        alfatihaValueIndex = Array.BinarySearch<long>(alfatihaValue.IsPrime() ? Numbers.Primes : Numbers.Composites, alfatihaValue);
                    break;
                case NumberType.AdditivePrime:
                        alfatihaValueIndex = Array.BinarySearch<long>(alfatihaValue.IsAdditivePrime() ? Numbers.AdditivePrimes : Numbers.AdditiveComposites, alfatihaValue);                    
                    break;
                case NumberType.PurePrime:
                        alfatihaValueIndex = Array.BinarySearch<long>(alfatihaValue.IsPurePrime() ? Numbers.PurePrimes : Numbers.PureComposites, alfatihaValue);
                    break;
            }

            if (alfatihaValueIndex > -1) {
                valueDifference = bismAllahValue - alfatihaValueIndex;
            }

            numerologySystem.BismAllah = bismAllahValue;
            numerologySystem.AlFatihaIndex = alfatihaValueIndex;
            numerologySystem.AlFatihaIndexType = nType;
            numerologySystem.Difference = valueDifference;
            
            return valueDifference;
        }
    }
     */
}